package com.gitee.wsl.coroutines.atomic

import kotlinx.atomicfu.locks.SynchronizedObject
import kotlinx.atomicfu.locks.synchronized
import kotlin.concurrent.Volatile

abstract class OnceReadValue<P, T> :SynchronizedObject() {
    @Volatile
    private var isRead = false

    private var cacheValue: T = TODO()

    operator fun get(param: P): T {
        if (isRead) {
            return cacheValue
        }
        synchronized(this) {
            if (!isRead) {
                cacheValue = read(param)
                isRead = true
            }
        }
        return cacheValue
    }

    protected abstract fun read(param: P): T
}